package cn.tlb.gl.tri_texture;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.opengl.GLSurfaceView;
import android.opengl.GLUtils;
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity;

import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;

import javax.microedition.khronos.egl.EGLConfig;
import javax.microedition.khronos.opengles.GL10;

import cn.tlb.xutilsdownload.R;

public class TriangleTextureActivity extends AppCompatActivity {

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(new MyGLSurfaceView(this));
    }
}

class MyGLSurfaceView extends GLSurfaceView{

    public MyGLSurfaceView(Context context) {
        super(context);
        setRenderer(new TriangleTextureRenderer(context));
    }
}

class TriangleTextureRenderer implements GLSurfaceView.Renderer{

    float[] vertex = {
            0,      0,      0,
            0.5f,   0,      0,
            0,      0.5f,   0
    };

    byte[] indeces = {
            0,1,2
    };

    float[] textures = {
            0,  1,
            1,  1,
            0,  0
    };

    FloatBuffer vertexBuffer;
    ByteBuffer indicesByteBuffer;
    FloatBuffer textureBuffer;
    Context context;
    int textureID;
    public TriangleTextureRenderer(Context context) {
        vertexBuffer = array2FloatBuffer(vertex);
        indicesByteBuffer = ByteBuffer.wrap(indeces);
        textureBuffer = array2FloatBuffer(textures);
        this.context = context;
    }

    @Override
    public void onSurfaceCreated(GL10 gl, EGLConfig config) {
        gl.glDisable(GL10.GL_DITHER);
        gl.glHint(GL10.GL_PERSPECTIVE_CORRECTION_HINT, GL10.GL_FASTEST);
        gl.glShadeModel(GL10.GL_SMOOTH);
        gl.glClearColor(0, 0, 0, 0);
        gl.glEnable(GL10.GL_TEXTURE_2D);
        gl.glEnable(GL10.GL_DEPTH_TEST);
        gl.glDepthFunc(GL10.GL_LEQUAL);

        // load texture
        Bitmap bitmap = BitmapFactory.decodeResource(context.getResources(), R.drawable.skycubemap1);
        int[] textures = new int[1];
        gl.glGenTextures(1, textures, 0);
        textureID = textures[0];
        gl.glBindTexture(GL10.GL_TEXTURE_2D, textureID);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER, GL10.GL_NEAREST);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MAG_FILTER, GL10.GL_LINEAR);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S, GL10.GL_REPEAT);
        gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T, GL10.GL_REPEAT);
        GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, bitmap, 0);

        bitmap.recycle();
    }

    @Override
    public void onSurfaceChanged(GL10 gl, int width, int height) {
        gl.glViewport(0, 0, width, height);
        gl.glLoadIdentity();
        gl.glMatrixMode(GL10.GL_PROJECTION);
        float ratio = (float)width/height;
        gl.glFrustumf(-ratio, ratio, -1, 1, 1, 10);
    }

    @Override
    public void onDrawFrame(GL10 gl) {
        gl.glClear(GL10.GL_DEPTH_BUFFER_BIT|GL10.GL_COLOR_BUFFER_BIT);
        gl.glMatrixMode(GL10.GL_MODELVIEW);
        gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);

        // draw triangle
        gl.glLoadIdentity();
        gl.glTranslatef(0, 0, -2);
        gl.glVertexPointer(3, GL10.GL_FLOAT, 0, vertexBuffer);
        gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, textureBuffer);
        gl.glBindTexture(GL10.GL_TEXTURE_2D, textureID);
        gl.glDrawElements(GL10.GL_TRIANGLE_STRIP, indicesByteBuffer.remaining(), GL10.GL_UNSIGNED_BYTE, indicesByteBuffer);

        gl.glFinish();
        gl.glDisableClientState(GL10.GL_VERTEX_ARRAY);
        gl.glDisableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
    }

    private FloatBuffer array2FloatBuffer(float fs[]){
        ByteBuffer byteBuffer = ByteBuffer.allocateDirect(fs.length * 4);
        byteBuffer.order(ByteOrder.nativeOrder());
        FloatBuffer floatBuffer = byteBuffer.asFloatBuffer();
        floatBuffer.put(fs);
        floatBuffer.position(0);
        return floatBuffer;
    }
}
